/**
 * @file 主路由
 * @date 2025/11/07 17:37:31
 * @author lyqjob@yeah.net
 */
import { useEffect, useState, Suspense } from 'react'
import { useRoutes , useNavigate ,useLocation } from "react-router-dom";
import { useSelector, useDispatch } from 'react-redux';
import { Skeleton, Spin } from 'antd';
import getLazyComponent from './asynccomponents';
import components from './staticcomponents';
import routers from './baseRouter';
import { setmenus, setpermissions, setasyncfiles } from "@/store/reducers/global";
import { getMenusTree } from "@/utils/utils"
import { adminApi } from "@/services/admin";

// 解决懒加载第一次加载时的闪烁问题
const lazyComponent = (Component) => {
    return (
        <Suspense fallback={<Skeleton active />}>
            <Component />
        </Suspense>
    );
}

const MainRoute = () => {
    const navigate = useNavigate();
    const dispatch = useDispatch();
    const location = useLocation();
    const [isLoading, setLoading] = useState(true);
    const [routes, setRoutes] = useState(routers);
    const asyncfiles = useSelector((state) => state.global.asyncfiles);
    const userId = useSelector((state) => state.global.userInfo.id);

    // 获取菜单和权限数据
    const fetchMenuAndPermissions = async () => {
        setLoading(true);
        
        if(location.pathname === '/login'){
            setLoading(false)
            return
        }

        if(!localStorage.getItem('access_token')){
            setLoading(false)
            navigate('/login',{replace:true})
            return
        }
        
        // 从服务器获取最新数据
        const [menuResponse, permissionResponse] = await Promise.all([
            adminApi.getMenusByUserId(userId),
            adminApi.getPermissionsByUserId(userId)
        ]);

        if(menuResponse[0] || permissionResponse[0]){
            setLoading(false)
            navigate('/login',{replace:true})
            return
        }

        if (menuResponse[1] && menuResponse[1].code === 200) {
            const menuData = menuResponse[1].data;
            const flatFiles = menuData.filter(item => item.node_type !== 1  && item.component_path)
            .map(item => ({
                path: item.route_path, 
                filepath: item.component_path, 
                title: item.name 
            }));

            const treeMenus = getMenusTree(menuData);
            setLoading(false)
            dispatch(setmenus(treeMenus));
            dispatch(setasyncfiles(flatFiles));
            
            if (permissionResponse[1] && permissionResponse[1].code === 200) {
                const permissionData = permissionResponse[1].data;
                dispatch(setpermissions(permissionData));
            }
        }
    };




    const routeElement = useRoutes(routes);

    useEffect(() => {
        if (asyncfiles.length > 0) {
            const newAsyncRouter = asyncfiles
                .map((item) => {
                    const p = (item.filepath || '').trim()
                        .replace(/^\.?\//, '')
                        .replace(/^@\/pages\//, '')
                        .replace(/^pages\//, '')
                        .replace(/^src\/pages\//, '');
                    const Comp = getLazyComponent(p);
                    return {
                        path: item.path,
                        element: lazyComponent(Comp)
                    };
                })
                .filter(Boolean);

            const updatedRoutes = [...routers];
            updatedRoutes[0].children.push(...newAsyncRouter);
            setRoutes(updatedRoutes);
            return
        }
    }, [asyncfiles]);

    useEffect(() => {
        fetchMenuAndPermissions();
        
        // 监听认证状态重置事件
        const handleResetStates = () => {
            setLoading(false);
        };
        
        window.addEventListener('auth:reset-states', handleResetStates);
        
        return () => {
            window.removeEventListener('auth:reset-states', handleResetStates);
        };
    }, []);

    // useEffect(() => {
    //     // window?.process?.done();
    // }, [routeElement]);

    if (isLoading) {
        return <Spin size="large" />;
    }

    return routeElement;
};

export default MainRoute;